#
#   Copyright EAVISE
#   Author: Maarten Vandersteegen
#
"""
Dollar
------
"""

from .detection import *

__all__ = ["DollarDetection", "DollarParser"]


class DollarDetection(Detection):
    """ Dollar image detection """

    def serialize(self):
        """ generate a dollar detection string """

        raise NotImplementedError

    def deserialize(self, string, class_label_map):
        """ parse a dollar detection string """
        elements = string.split(',')
        self.class_label = class_label_map[0]
        frame_nr = int(elements[0]) - 1
        self.x_top_left = float(elements[1])
        self.y_top_left = float(elements[2])
        self.width = float(elements[3])
        self.height = float(elements[4])
        self.confidence = float(elements[5])

        self.object_id = 0


class DollarParser(Parser):
    """
    This parser is designed to parse the text based dollar detections generated by Piotr Dollar's toolbox_
    and the EAVISE PeopleDetect framework.

    Keyword Args:
        class_label_map (list): a list containing one string element with the name of the class the detector \
        is trained for (this format only supports single class detections)

    A text file contains multiple detections over multiple images where each line in the file represents one
    detection bounding box.
    Each line is a comma separated list of values structured as follows:

        <image_id>,<x>,<y>,<w>,<h>,<score>

    =========  ===========
    Name       Description
    =========  ===========
    image_id   image identifier that this annotation belong to (integer)
    x          top left x coordinate of the bounding box in pixels (integer)
    y          top left y coordinate of the bounding box in pixels (integer)
    w          width of the bounding box in pixels (integer)
    h          height of the bounding box in pixels (integer)
    score      relative detection score not limited between boundaries (float)
    =========  ===========

    Example:
        >>> video_000.txt
            20,503.75,213,20.5,50,74.8391
            20,540.8,166.4,37.4857,91.4286,56.4761
            20,519.034,186.602,31.6574,77.2131,51.2428

    Note:
        The image identifier is subtracted with 1 during parsing so parsed image id 1 refers to
        image 0. This is due to MATLAB legacy.

    Note:
        For calculating PR or MR vs FPPI curves, the score does not need to be normalized between 0 and 1
        since the scores are treated relatively

    Warning:
        Serialize is currently not implemented

    .. _toolbox: https://github.com/pdollar/toolbox/blob/master/detector/bbGt.m
    """
    parser_type = ParserType.SINGLE_FILE
    box_type = DollarDetection

    def __init__(self, **kwargs):
        """ Only the first element of the class label map is used since this format
            does not support class labels
        """
        try:
            self.class_label_map = kwargs['class_label_map']
        except KeyError:
            raise ValueError("Dollar detection format requires a 'class_label_map' kwarg")

    def serialize(self, detections):
        """ Serialize input detection to dollar detection strings """

        raise NotImplementedError

    def deserialize(self, string):
        """ Parse a json string into a dictionary of detections """
        result = {}
        for line in string.splitlines():
            img_id = str(int(line.split(',')[0]) - 1)
            if img_id not in result:
                result[img_id] = []
            det = self.box_type()
            det.deserialize(line, self.class_label_map)
            result[img_id] += [det]

        return result
